// 抽象的动物类
class Animal {
    constructor(name, type, breed, price) {
        if (new.target === Animal) {
            throw new Error("Animal 是一个抽象类，不能直接实例化");
        }
        this.name = name;  // 名字
        this.type = type;  // 种类
        this.breed = breed;  // 品种
        this.price = price;  // 价格
    }

    // 吃饭方法
    eat() {
        console.log(`${this.name} 正在吃饭`);
    }

    // 睡觉方法
    sleep() {
        console.log(`${this.name} 正在睡觉`);
    }

    // 玩的方法 - 抽象方法，由子类实现
    play() {
        throw new Error("抽象方法 play() 必须在子类中实现");
    }

    // 叫的方法 - 抽象方法，由子类实现
    makeSound() {
        throw new Error("抽象方法 makeSound() 必须在子类中实现");
    }
}

// 小猫类
class Cat extends Animal {
    constructor(name, breed, price) {
        super(name, "猫", breed, price);
    }

    play() {
        console.log(`${this.name} 正在玩`);
        this.makeSound(); // 猫玩的时候会叫
    }

    makeSound() {
        console.log(`${this.name} 喵喵叫`);
    }
}

// 小狗类
class Dog extends Animal {
    constructor(name, breed, price) {
        super(name, "狗", breed, price);
    }

    play() {
        console.log(`${this.name} 正在玩`);
    }

    makeSound() {
        console.log(`${this.name} 汪汪叫`);
    }
}

// 实例化小猫对象
const cat1 = new Cat("咪咪", "暹罗猫", 1000);
const cat2 = new Cat("小花", "布偶猫", 2000);

// 调用小猫的方法
cat1.eat();
cat1.sleep();
cat1.play();

cat2.eat();
cat2.sleep();
cat2.play();

// 实例化小狗对象
const dog1 = new Dog("旺财", "哈士奇", 1500);
const dog2 = new Dog("小黑", "拉布拉多", 1800);

// 调用小狗的方法
dog1.eat();
dog1.sleep();
dog1.play();
dog1.makeSound();

dog2.eat();
dog2.sleep();
dog2.play();
dog2.makeSound();